/*
 *  $Id: SummonableCard.cs 1083 2010-05-24 10:28:38Z thenn.erannor $
 *	This file is a part of Ragima CCG.
 *	(C) 2008-2009 Ragima development group.
 *
 *	Licensed under the terms of the GNU GPL License version 2.
 *
 */

using System.Collections.Generic;

using AgateLib.Geometry;

namespace Ragima {
    /// <summary>
    /// Призываемая карта
    /// Предоставляет: врожденные эффекты, способности
    /// </summary>
    public abstract class SummonableCard: Card {
        public SummonableCard(string id): base(id) {}

        public virtual void CollectNaturalAffects(ICollector<Affect> affects) {
            SetNaturalAffects(affects);
        }
        public virtual void CollectAbilities(ICollector<AbilityCard> abilities) {
            SetAbilities(abilities);
        }

        public virtual void SetNaturalAffects(ICollector<Affect> affects) {}
        public virtual void SetAbilities(ICollector<AbilityCard> abilities) {}

        private AffectWeightCollector _affectWeight;
        private AbilityWeightCollector _abilityWeight;

        protected override int GetWeight() {
            if (_affectWeight == null) _affectWeight = new AffectWeightCollector(this);
            if (_abilityWeight == null) _abilityWeight = new AbilityWeightCollector(this);
            return base.GetWeight() + _affectWeight.Weight + _abilityWeight.Weight;
        }

        private IconList _icons;

        public override bool DrawHelp(int x, int y) {
            bool draw = base.DrawHelp(x, y);
            if (draw) {
                if (_icons == null) _icons = new IconList(this);
                _icons.Draw(new Point(x+22, y+31));
            }
            return draw;
        }

        private class IconList: ICollector<Affect> {
            private AffectIconDictionary _icons;
            private AffectIconItems _items;

            public IconList(SummonableCard card) {
                _icons = new AffectIconDictionary();
                _items = new AffectIconItems(16);
                card.CollectNaturalAffects(this);
            }

            public void Draw(Point start) {
                _items.Update(_icons, start);
                _items.Draw();
            }

            public void Add(Affect affect) {
                _icons.Add(affect);
            }
            public void Add<T>() where T: Affect, new() {
                Add(new T());
            }
        }

        private class AffectWeightCollector: ICollector<Affect> {
            private Card _card;
            private int _weight;

            public AffectWeightCollector(SummonableCard card) {
                _card = card;
                _weight = 0;
                card.CollectNaturalAffects(this);
            }

            public int Weight {
                get { return _weight; }
            }

            public void Add(Affect affect) {
                _weight += affect.GetWeight(_card);
            }
            public void Add<T>() where T: Affect, new() {
                Add(new T());
            }
        }
        private class AbilityWeightCollector: ICollector<AbilityCard> {
            private int _weight;

            public AbilityWeightCollector(SummonableCard card) {
                _weight = 0;
                card.CollectAbilities(this);
            }

            public int Weight {
                get { return _weight; }
            }

            public void Add(AbilityCard ability) {
                _weight += ability.Weight;
            }
            public void Add<T>() where T: AbilityCard, new() {
                Add(CardManager.GetAbility<T>());
            }
        }
    }
}
